
#include "block_heaps.h"


namespace	memory
{

	SLIST_ENTRY*	clear_entry( SLIST_ENTRY* entry )
	{
		if( entry != NULL )
		{
			entry->Next = NULL;
		}

		return entry;
	}

	block_heaps::block_heaps()
		: heaps_( NULL )
		, count_( 0 )
	{
	}

	block_heaps::~block_heaps()
	{
		destroy();
	}

	bool	block_heaps::create( size_t parallelism )
	{
		heaps_ = new slist_entry_heap[parallelism];
		if( heaps_ == NULL )
		{
			return false;
		}

		for( size_t i = 0; i < parallelism; ++i )
		{
			if( heaps_[i].create() == false )
			{
				return false;
			}
		}

		count_ = parallelism;
		return true;
	}

	void	block_heaps::destroy()
	{
		count_ = 0;
		if( heaps_ != NULL )
		{
			delete [] heaps_;
			heaps_ = NULL;
		}
	}

	SLIST_ENTRY*	block_heaps::alloc( size_t heap_idx, size_t size )
	{
		slist_entry_heap* heap = at( heap_idx );
		if( heap != NULL )
		{
			return clear_entry( heap->alloc( size ) );
		}

		return NULL;
	}

	SLIST_ENTRY*	block_heaps::try_alloc( size_t heap_idx, size_t size )
	{
		slist_entry_heap* heap = at( heap_idx );
		if( heap != NULL )
		{
			return clear_entry( heap->try_alloc( size ) );
		}

		return NULL;
	}

	bool	block_heaps::free( size_t heap_idx, SLIST_ENTRY* entry )
	{
		slist_entry_heap* heap = at( heap_idx );
		if( heap != NULL )
		{
			return heap->free( entry );
		}

		return false;
	}

	size_t	block_heaps::count()	const
	{
		return count_;
	}

	slist_entry_heap*	block_heaps::at( size_t heap_idx )	const
	{
		slist_entry_heap* heap = NULL;
		assert( heaps_ != NULL );
		if( heaps_ != NULL )
		{
			if( 0 <= heap_idx && heap_idx < count_ )
			{
				heap = &heaps_[heap_idx];
			}
		}

		assert( heap != NULL );
		return heap;
	}

}